using COC.Character.AI.Internal.FSM;
using COC.Tools.AI.Motion;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using COC;
using COC.CEvent;
using COC.Debug;
namespace COC.Character
{
    /// <summary>
    /// applies all character scripts,including military troops,heroic role,buildings etc.It's a important class.
    /// 用于所有角色的脚本，包括兵,英雄角色，建筑等。
    /// </summary>
    public class BaseBehaviour : MonoBehaviour, CEventNotifier
    {
        //是否启用脚本
        protected bool enableAllScripts = false;
        void Start()
        {
            OnStart();
        }

        void Awake()
        {
            OnAwake();
        }
        void Destroy()
        {
            OnDestroy();
        }
        void Update()
        {
            OnUpdate();
        }
        void LateUpdate()
        {
            OnLateUpdate();
        }
        void FixedUpdate()
        {
            OnFixedUpdate();
        }

        public virtual void OnFixedUpdate()
        {
        }

        /// <summary>
        ///脚本启用Update方法
        /// </summary>
        public virtual void OnUpdate()
        {

        }

        public virtual void OnLateUpdate()
        {

        }
        /// <summary>
        ///当脚本启用后执行该方法
        /// </summary>
        public virtual void OnStart()
        {

        }
        /// <summary> 
        ///不管脚本是否启用都执行该方法 
        /// </summary>
        public virtual void OnAwake()
        {

        }
        /// <summary>
        /// 当删除该脚本时调用该方法，用于对资源清理工作。
        /// </summary>
        public virtual void OnDestroy()
        {

        }
        /// <summary>
        /// Instantiates the and disable script by touch.按照触发位置实例一对象，但不启用对象的脚本
        /// </summary>
        /// <returns>The instantiate object by input position.</returns>
        /// <param name="target">Target.需要实例的prefab</param>
        /// <param name="input">Input.触发位置</param>
        /// <param name="targetCameraTag">Target camera tag.摄像机标签</param>
        /// <param name="index">Index.</param>
        /// <param name="colliderTag">Collider tag.鼠标左=0/中=1/右=2键触发 还是手势触发(0表示第一个手势)</param>
        /// <param name="enableScript">enable script or not after instance of prefab</param>
        public Object InstantiateWithScriptByMouseOrTouch(Object targetPrefab, Vector3 input, string targetCameraTag, int index, string colliderTag, bool enableScript)
        {
            return InstantiateToInputPosition(targetPrefab, input, targetCameraTag, index, colliderTag, enableScript, null);
        }



        /// <summary>
        /// Instantiates to input position.
        /// </summary>
        /// <returns>The instantiate object by input position.</returns>
        /// <param name="target">Target to be instantiated.</param>
        /// <param name="coordinate">Input method:Input.GetMousePosition,Input.GetTouch[0] etc</param>
        /// <param name="targetCameraTag"> which camera that screen point to Ray</param>
        /// <param name="index">mouse: left mouse,middle mouse or right mouse.Touch:first finger or second</param>
        /// <param name="colliderTag">Collider tag.physic to collider a  this named tag rigidBody</param>
        /// <param name="enableAllScripts">是否启用所有脚本If set to <c>true</c> enable all scripts.</param>
        /// <param name="rigisterScriptsAndEnable">which script to be enabled when rigister scripts by dictionary</param>
        Object InstantiateToInputPosition(Object target, Vector3 coordinate, string targetCameraTag, int index, string colliderTag, bool enableAllScripts, Dictionary<string, bool> rigisterScriptsAndEnable)
        {
#if UNITY_ANDROID_1
		//info.text=Input.touches.Length+"";
		if(Input.touchCount==1){
			if(Input.GetTouch(i).phase==TouchPhase.Began){
				info.text="touched:"+Input.touches.Length;
				GameObject go=Instantiate(this.gameObject,transform.position,transform.rotation) as GameObject;
				go.transform.Translate(new Vector3(this.gameObject.transform.position.x+UnityEngine.Random.value*10,
				                                   this.gameObject.transform.position.y,
				                                   this.gameObject.transform.position.z));
				//go.transform.position.x=(this.gameObject.transform.position.x+UnityEngine.Random.value*10);
				Debug.Log("Have Touched "+touched+"Times");
			}
		}
#elif UNITY_IPHONE
		
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR

#else
		
#endif

            if (Input.GetMouseButtonUp(index))
            {

                Vector3 mousePos = new Vector3(coordinate.x, coordinate.y, coordinate.z);
                Vector3 wordPos;
                Camera currCamera = GameObject.FindWithTag(targetCameraTag).camera;
                //info.text = "x = " + Input.mousePosition.x + ";y = " + Input.mousePosition.y + " ;z = " + Input.mousePosition.z;
                Ray ray = currCamera.ScreenPointToRay(mousePos);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit,
                         Mathf.Infinity))
                {
                    wordPos = hit.point;
                    if (hit.collider.tag == colliderTag)
                    {
                        if (false)
                            DebugTool.DrawLine(hit.point, coordinate, Color.red);
                        wordPos.x = Mathf.Round(wordPos.x);
                        wordPos.y = Mathf.Round(wordPos.y);
                        wordPos.z = Mathf.Round(wordPos.z);
                        //float fDist = 0.0f;
                        //wordPos=ray.GetPoint(fDist);
                        if (false)
                            DebugTool.DrawLine(ray.origin, ray.direction * 10, Color.cyan);
                    }
                }
                else
                {
                    wordPos = currCamera.ScreenToWorldPoint(mousePos);
                }
                Transform t = (Transform)Instantiate(target, wordPos, Quaternion.identity);

                t.name = transform.name + "_" + (System.Guid.NewGuid());
                if (!enableAllScripts)
                {
                    Component[] scripts = t.GetComponents(System.Type.GetType(this.GetType().FullName));
                    foreach (Component c in scripts)
                    {
                        ((BaseBehaviourSupport)c).enabled = false;
                    }
                }
                t.localScale = transform.localScale;
                return (Object)t;
                //t.animation.Play ("XBMove");


                //info.text=""+(++touched);
                //go.transform.Translate(Vector3.forward*UnityEngine.Random.value*10);
                //Destroy(this.gameObject);
                //canClone = false;
                //	yield return null;
            }
            return null;
            //canClone = false;

        }

        public GUIElement[] availableGUI(Vector3 mousePosition)
        {
            Object[] panels = GameObject.FindObjectsOfType(typeof(UIPanel));
            foreach (Object p in panels)
            {
                //((UIPanel)p).
            }
            return null;
        }

        /// <summary>
        /// Send the broadcast when service deal a event from source successfully or failure and broadcast a notification.Used to service invoke a call back
        /// </summary>
        /// <param name="notification">Notification.</param>
        public void SendBroadcast(CNotification notification)
        {
            DebugTool.Log("test a notifier:" + notification.message);
            Notifier(notification);
        }

        public void Notifier(CNotification n)
        {
            DebugTool.Log("I'm a notifier");
        }
        #region fSMConnector's  call
        /// <summary>
        /// attach on AIBehave class
        /// </summary>
        public void onAttach(FSMConnector connector)
        {
            GetComponent<AIBehave>().connector = connector;

            GetComponent<AIBehave>().open(true);
        }
        /// <summary>
        /// dettach on AIBehave class
        /// </summary>
        public void onDettach()
        {
            GetComponent<AIBehave>().connector = null;
            GetComponent<AIBehave>().open(false);
        }
        public void Call(FSMState state)
        {
            GetComponent<AIBehave>().connector.Call(state);
        }

        public void Return()
        {
            GetComponent<AIBehave>().connector.Return();
        }
        #endregion
    }

}